<template>
  <section>
    <div class="bg-white pl-[10px]">
      <el-row :gutter="10" class="my-[10px]">
        <el-col :span="3">
          <el-input v-model="state.searchName" placeholder="搜索商品名" class="h-[40px]" @change="searchNameChange" clearable>
            <template #prefix>
              <el-icon class="el-input__icon"><i-ep-search /></el-icon>
            </template>
          </el-input>
        </el-col>
        <el-col :span="3">
          <el-select class="w-full" v-model="state.searchIP" placeholder="选择IP" size="large" clearable
            @change="searchIPChange">
            <el-option v-for="item in (state.ip as any)" :key="item.value" :label="item.key" :value="item.value" />
          </el-select>
        </el-col>
        <el-col :span="3">
          <el-select class="w-full" v-model="state.searchCategory" placeholder="选择分类" size="large" clearable
            @change="selectCategoryChange">
            <el-option v-for="item in (state.category as any)" :key="item.value" :label="item.key" :value="item.value" />
          </el-select>
        </el-col>
        <el-col :span="2">
          <el-select class="w-full" v-model="state.searchSource" placeholder="选择货源" size="large" clearable
            @change="selectSourceChange">
            <el-option v-for="item in (state.source as any)" :key="item.value" :label="item.key" :value="item.value" />
          </el-select>
        </el-col>
        <el-col :span="2">
          <el-select class="w-full" v-model="state.searchStatus" placeholder="选择状态" size="large" clearable
            @change="selectStatusChange">
            <el-option v-for="item in (state.status as any)" :key="item.value" :label="item.key" :value="item.value" />
          </el-select>
        </el-col>
        <el-col :span="11">
          <div class="flex flex-1 justify-end mr-[20px] overflow-hidden">
            <el-button size="large" type="warning" @click="downLoadTemplate">下载模版</el-button>
            <el-upload class="mx-3" @change="importExcl" :auto-upload="false" :show-file-list="false">
              <el-button size="large" type="info">导入数据</el-button>
            </el-upload>

            <el-button size="large" type="success" @click="exportExcl">导出Excl</el-button>
            <el-button size="large" type="primary" @click="state.showAddProduct = true">新增商品</el-button>
          </div>
        </el-col>
      </el-row>
      <el-row>
        <el-col class="mr-[10px]">
          <el-table ref="dataTable" :data="state.data" border height="calc(100vh - 170px)" style="width: 99%"
            header-cell-class-name="text-black" @row-dblclick="toDetail">
            <el-table-column label="序号" width="60">
              <template #default="{ $index }">
                <p class="text-center">{{ $index + 1 }}</p>
              </template>
            </el-table-column>
            <el-table-column align="center" prop="enterDate" label="进货日期" width="120">
              <template #default="scope">
                <p class="text-center">
                  {{ dayjs(scope.row.enterDate).format("YYYY-MM-DD") }}
                </p>
              </template>
            </el-table-column>
            <el-table-column align="center" prop="cover" label="图片" width="180">
              <template #default="scope">
                <my-image fit="cover" class="w-[150px] h-[120px]" :src="scope.row.cover" />
              </template>
            </el-table-column>
            <el-table-column align="center" prop="name" label="商品名称" />
            <el-table-column align="center" prop="pIp" label="IP" width="180" />
            <el-table-column align="center" prop="categoryDesc" label="类型" width="150" />
            <el-table-column align="center" sortable prop="boxPrice" label="整盒价(￥)" width="120" />
            <el-table-column align="center" sortable prop="stock" label="库存" width="80" />
            <el-table-column align="center" prop="sourceDesc" label="货源" width="100" />
            <el-table-column align="center" prop="statusDesc" label="状态" width="100">
              <template #default="scope">
                <p v-if="scope.row.statusDesc === (state.status?.[1] as any)?.key" class="status-tag bg-[#f64f59]">
                  {{ scope.row.statusDesc }}
                </p>
                <p v-else-if="scope.row.statusDesc === (state.status?.[2] as any)?.key" class="status-tag bg-[#c471ed]">
                  {{ scope.row.statusDesc }}
                </p>
                <p v-else-if="scope.row.statusDesc === (state.status?.[3] as any)?.key" class="status-tag bg-[#12c2e9]">
                  {{ scope.row.statusDesc }}
                </p>
                <p v-else>{{ scope.row.statusDesc }}</p>
              </template>
            </el-table-column>
            <el-table-column align="center" sortable prop="buyPrice" label="进价(￥)" width="110" />
            <el-table-column align="center" sortable prop="sellPrice" label="售价(￥)" width="110" />

            <!-- <el-table-column align="center" sortable prop="guidePrice" label="指导价(￥)" width="120" />
            <el-table-column align="center" sortable prop="breakPrice" label="折扣价(￥)" width="120" /> -->
            <el-table-column fixed="right" align="center" label="操作" width="150">
              <template #default="{ row, column, $index }">
                <!-- <el-button style="margin:4px" type="primary" circle @click="toDetail(row, column)">
                  <el-icon><i-ep-View /></el-icon>
                </el-button> -->
                <el-button style="margin:4px" type="success" circle @click="editStock(0, row)">
                  <el-icon><i-ep-CirclePlusFilled /></el-icon>
                </el-button>
                <el-button style="margin:4px" type="warning" circle @click="editStock(1, row)">
                  <el-icon><i-ep-RemoveFilled /></el-icon>
                </el-button>
                <el-button style="margin:4px" type="primary" circle @click="editProduct(row)">
                  <el-icon><i-ep-Edit /></el-icon>
                </el-button>
                <el-button style="margin:4px" type="danger" circle @click="deleteProduct(row)">
                  <el-icon><i-ep-Delete /></el-icon>
                </el-button>
                <el-button style="margin:4px" type="primary" circle @click="addImage(row)">
                  <el-icon><i-ep-Upload /></el-icon>
                </el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-col>
      </el-row>
      <el-row class="mt-[10px]" justify="end">
        <el-col class="flex flex-1 justify-end items-center">
          <el-button type="primary" @click="loadProductList(true)">
            <el-icon><i-ep-Refresh /></el-icon>&nbsp;刷新
          </el-button>
          <el-pagination class="flex justify-end mx-[20px]" background :current-page="state.page" :page-size="1"
            :total="state.total" layout="prev, pager, next" @current-change="pageNextOrBefore" />
        </el-col>
      </el-row>
    </div>

    <operate-product v-if="state.showAddProduct" v-model="state.showAddProduct" :source="state.source"
      :status="state.status" :category="state.category" :ip="state.ip" v-model:pageType="state.pageType"
      v-model:currentProduct="state.currentProduct" :refresh="loadProductList" />

    <operate-stock v-if="state.showStock" v-model="state.showStock" v-model:pageType="state.pageType"
      v-model:currentProduct="state.currentProduct" :refresh="loadProductList" />

    <import-excl-modal v-if="state.showExclData" v-model="state.showExclData" v-model:data="state.exclData"
      :status="state.status" :refresh="loadProductList" />

    <product-image v-model="state.showUploadImage" :data="state.currentProduct" />
  </section>
</template>

<script lang="ts" setup>
import ProductService from "@/api/ProductService";
import { dayjs } from "element-plus";
import XLSX from "xlsx-js-style";
import { Product } from "@/components/product/type";

const router = useRouter()
const state = reactive({
  data: [],
  total: 0,
  page: 1,
  searchName: "",
  searchIP: "",
  searchCategory: "",
  searchSource: "",
  searchStatus: "",
  category: [],
  source: [],
  ip: [],
  status: [],
  showAddProduct: false,
  showStock: false,
  pageType: 0,
  currentProduct: {} as Product,

  exclData: [] as any[],
  showExclData: false,

  showUploadImage: false,
});

const _ref = shallowRef({
  pageSize: 10,
});
const dataTable = ref()

const searchNameChange = () => {
  state.page = 1;
  loadProductList();
};

const searchIPChange = () => {
  state.page = 1;
  loadProductList();
};

const selectCategoryChange = () => {
  state.page = 1;
  loadProductList();
};

const selectStatusChange = () => {
  state.page = 1;
  loadProductList();
};

const selectSourceChange = () => {
  state.page = 1;
  loadProductList();
};

const loadProductList = async (showLoading?: boolean) => {
  const { pageSize } = _ref.value;
  const { page, searchName, searchIP, searchCategory, searchSource, searchStatus } = state;
  if (page === -1) return;
  showLoading && Utils.Modal().loading('加载中~')
  const params = {
    page,
    pageSize,
    name: searchName,
    pIp: searchIP,
    category: searchCategory,
    source: searchSource,
    status: searchStatus,
  };
  const [err, res] = await ProductService.loadProductList(params);
  showLoading && Utils.Modal().closeLoading()
  if (err) {
    return Utils.Modal().msgSuccess(err);
  }
  state.data = res.data?.result || [];
  state.total = res.data?.total;
};

const loadProductCategory = async () => {
  const [err, res] = await ProductService.loadProductCategory();
  if (err) {
    return Utils.Modal().msgSuccess(err);
  }
  const { category, source, ip, status } = res.data || {};
  state.category = category;
  state.source = source;
  state.ip = ip;
  state.status = status;
};

const pageNextOrBefore = (page: number) => {
  dataTable.value.setScrollTop(0)
  dataTable.value.setScrollLeft(0)
  state.page = page;
  loadProductList();
};

const deleteProduct = async (row: Product) => {
  const { pId, name } = row;
  if (!pId) return;
  const [err, res] = await Utils.Modal().confirm(`确定需要删除商品 “${name}” 吗？`);
  if (err) return;
  const [delErr, del] = await ProductService.deleteProduct(pId);
  if (delErr) {
    return Utils.Modal().msgError(delErr);
  }
  Utils.Modal().msgSuccess("删除成功~");
  state.page = 1;
  loadProductList();
};

const editProduct = (row: Product) => {
  state.pageType = 1;
  state.currentProduct = { ...row };
  state.showAddProduct = true;
};

const editStock = (type: number, row: Product) => {
  if (type === 1 && row.stock === 0) {
    return Utils.Modal().alertWarning("库存已不足~");
  }
  state.pageType = type;
  state.currentProduct = { ...row };
  state.showStock = true;
};

const toDetail = (row: Product, column: any) => {
  const href = router.resolve({
    path: `/product/detail`,
    query: { id: row.pId },
  }).href;
  //打开新的页面 到 href 这个页面
  window.open(href, "_blank");
}

const addImage = (row: Product) => {
  state.pageType = 1;
  state.currentProduct = { ...row };
  state.showUploadImage = true;
}

// 构建Excl样式
const buildExcel = (worksheet: string[][]) => {
  const workbook = XLSX.utils.book_new();
  const ws = XLSX.utils.aoa_to_sheet(worksheet)
  ws["!merges"] = [
    {
      s: { r: 0, c: 0 },
      e: { r: 0, c: 11 }, //合并范围是第1行第一列到第1行第10列
    }
  ]
  ws["!cols"] = [
    {
      wpx: 200,
    },
    {
      wpx: 350,
    },
    {
      wpx: 200,
    },
    {
      wpx: 200,
    },
    {
      wpx: 150,
    },
    {
      wpx: 60,
    },
    {
      wpx: 150,
    },
    {
      wpx: 120,
    },
  ];

  for (const key in ws) {
    if (ws[key] instanceof Object) {
      ws[key].s = {
        alignment: {
          vertical: 'center',
          horizontal: 'center',
          indent: 0,
          wrapText: true
        },
        font: {
          name: '微软雅黑',
          sz: 13,
          color: { rgb: '#302d2d' },
          bold: false,
          italic: false,
          underline: false
        },
        border: {
          top: { style: 'thin' },
          bottom: { style: 'thin' },
          left: { style: 'thin' },
          right: { style: 'thin' }
        },
        height: 50,
      }
      const value = ws[key]?.v || ''
      if (key.indexOf('A') > -1 && value.startsWith('http')) {
        ws[key].l = { Target: value, Tooltip: '点击查看图片' }
      }
    }
  }

  const range = XLSX.utils.decode_range(ws["!ref"] as any)
  const rowStyle = [{ hpx: 50 }, { hpx: 40 }]
  for (let i = range.s.r + 2; i < range.e.r + 2; i++) {
    rowStyle.push({ hpx: 80 })
  }
  ws["!rows"] = rowStyle

  // 将工作表添加到工作簿
  XLSX.utils.book_append_sheet(workbook, ws, 'Sheet1');
  // 生成Excel文件
  XLSX.writeFile(workbook, `${dayjs().format('YYYY-MM-DD HH-mm-ss')}.xlsx`)
}

// 下载模版
const downLoadTemplate = async () => {
  // 创建一个工作表
  const worksheet = [
    [`产品导入模版`],
    [
      'IP',
      '商品名称',
      '品类',
      '货源',
      '入库情况',
      '入库日期',
      '进货价',
      '最终定价',
      '入库数量',
    ],
    [],
  ]

  buildExcel(worksheet)
}

const buildExclProduct = (result: any) => {
  const { category, source, status } = state
  const fn = (s: any[]) => s.reduce((obj, item: any) => obj.set(item.key, item.value), new Map())
  const _category = fn(category)
  const _source = fn(source)
  const _status = fn(status)
  const target: any[] = []
  let temp: any

  result.forEach((item: any) => {
    if (item['IP'] && item['商品名称']) {
      temp = {}
      temp.enterDate = item['入库日期'] ? dayjs(item['入库日期']).format('YYYY-MM-DD HH:mm:ss') : ''
      temp.name = item['商品名称']
      temp.pIp = item['IP']
      temp.category = _category.get(item['品类'])
      temp.categoryDesc = item['品类']
      temp.source = _source.get(item['货源'])
      temp.sourceDesc = item['货源']
      temp.status = _status.get(item['入库情况'])
      temp.statusDesc = item['入库情况']
      temp.buyPrice = item['进货价']
      temp.sellPrice = item['最终定价']
      temp.stock = item['入库数量']

      target.push(temp)
    }
  })

  state.exclData = target
  state.showExclData = true
}

const importExcl = async (e: any) => {
  if (e.status !== 'ready') return   // 防止触发两次
  if (e.length <= 0) {
    return Utils.Modal().msgWarning('请选择文件')
  }
  if (e.name.split('.')[1] !== 'xlsx') {
    return Utils.Modal().msgWarning('文件格式不正确，请上传xlsx格式')
  }

  const file = e.raw

  const readExclFile = (file: File): Promise<any[]> => new Promise(resolve => {
    const reader = new FileReader()
    reader.readAsArrayBuffer(file)
    reader.onload = async (ev: any) => {
      const target = ev.target.result
      const workbook = XLSX.read(target, { type: 'binary', cellDates: true })
      const wsName = workbook.SheetNames[0]
      const data = XLSX.utils.sheet_to_json(workbook.Sheets[wsName], {
        defval: '',
      })
      resolve(data)
    }
  })

  const data = await readExclFile(file)

  buildExclProduct(data)
}

// 导出模版
const exportExcl = async () => {
  const [err, res] = await ProductService.loadProductListAll()
  if (err) {
    return Utils.Modal().msgWarning("导出Excl失败~");
  }
  const data = res?.data || []
  if (!data.length) {
    return Utils.Modal().msgWarning("暂无商品数据~");
  }
  // 创建一个工作表
  const worksheet = [
    [`${dayjs().format('YYYY年MM月')}产品汇总`],
    [
      '封面图',
      '名称',
      'IP',
      '进货时间',
      '状态',
      '库存',
      '类别',
      '来源',
      '进价',
      '售价',
      '指导价',
      '折扣价',
    ],
  ]
  let obj: string[]
  data.forEach((_: any) => {
    obj = [
      _.cover,
      _.name,
      _.pIp,
      dayjs(_.enterDate).format('YYYY-MM-DD HH:mm:ss'),
      _.statusDesc,
      _.stock,
      _.categoryDesc,
      _.sourceDesc,
      _.buyPrice,
      _.sellPrice,
      _.guidePrice,
      _.breakPrice,
    ]
    worksheet.push(obj)
  })


  buildExcel(worksheet)
}

loadProductList();
loadProductCategory();
</script>

<style lang="scss" scoped>
.status-tag {
  color: #fff;
  border-radius: 10px;
  padding: 5px 10px;
  font-weight: bold;
  font-size: 12px;
  letter-spacing: 2px;
  text-align: center;
  font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
}
</style>
